// Copyright (C) 2023 即时通讯网(52im.net) & Jack Jiang.
// The RainbowChat Project. All rights reserved.
// 
// 【本产品为著作权产品，合法授权后请放心使用，禁止外传！】
// 【本次授权给：<北京小羊驼科技有限公司>，授权编号：<NT231212144350>，代码指纹：<A.702363430.550>，技术对接人微信：<ID: wxid_wbyootvkdcgj22>】
// 【授权寄送：<收件：苏先生、地址：北京市大兴区北京密码西区6号楼1单元301、电话：18613885610、邮箱：bd@huiyuanxiang-inc.com>】
// 
// 【本系列产品在国家版权局的著作权登记信息如下】：
// 1）国家版权局登记名(简称)和权证号：RainbowChat    （证书号：软著登字第1220494号、登记号：2016SR041877）
// 2）国家版权局登记名(简称)和权证号：RainbowChat-Web（证书号：软著登字第3743440号、登记号：2019SR0322683）
// 3）国家版权局登记名(简称)和权证号：RainbowAV      （证书号：软著登字第2262004号、登记号：2017SR676720）
// 4）国家版权局登记名(简称)和权证号：MobileIMSDK-Web（证书号：软著登字第2262073号、登记号：2017SR676789）
// 5）国家版权局登记名(简称)和权证号：MobileIMSDK    （证书号：软著登字第1220581号、登记号：2016SR041964）
// * 著作权所有人：江顺/苏州网际时代信息科技有限公司
// 
// 【违法或违规使用投诉和举报方式】：
// 联系邮件：jack.jiang@52im.net
// 联系微信：hellojackjiang
// 联系QQ号：413980957
// 授权说明：http://www.52im.net/thread-1115-1-1.html
// 官方社区：http://www.52im.net
package com.x52im.mall.logic.shop;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Paint;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.Gallery;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.eva.android.widget.DataLoadableActivity;
import com.eva.android.HttpServiceFactory4A;
import com.eva.android.widget.AListAdapter2;
import com.eva.android.widget.AsyncBitmapLoader;
import com.eva.android.widget.AsyncBitmapLoader.ImageCallBack;
import com.eva.android.widget.WidgetUtils;
import com.eva.android.widget.WidgetUtils.ToastType;
import com.eva.epc.common.util.CommonUtils;
import com.eva.framework.dto.DataFromClient;
import com.eva.framework.dto.DataFromServer;
import com.eva.framework.dto.SysActionConst;
import com.x52im.mall.IntentFactory;
import com.x52im.mall.MallGlobal;
import com.x52im.mall.ObjectFactory;
import com.x52im.mall.Utility;
import com.x52im.mall.dto.CommonProcessorConst;
import com.x52im.mall.shop.dto.Color;
import com.x52im.mall.shop.dto.Device;
import com.x52im.mall.shop.dto.Pic;
import com.x52im.rbchat.R;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 商品详细信息查看Activity实现类.
 * 
 * @author Jack Jiang(http://www.52im.net/space-uid-1.html)
 * @version 1.0
 */
public class GoodDetailActivity extends DataLoadableActivity 
{
	private final static String TAG = GoodDetailActivity.class.getSimpleName();
	
	/** 标签组件：商品短名称 */
	private TextView viewGoodName = null;
	/** 标签组件：商品描述 */
//	private TextView viewGoodDesc = null;
	/** 标签组件：商品售价 */
	private TextView viewGoodPrice = null;
	/** 标签组件：货币类型 */
	private TextView viewCurrencyType = null;
	/** 标签组件：参考价格 */
	private TextView viewRefPrice = null;
	
//	/** 标签组件：目标性别 */
//	private TextView viewForSex = null;
	
	private ListView saleListView = null;
	
	private ListView basicListView = null;
	
	private List<Color> colorList = new ArrayList<Color>();
	
//	/** 标签组件：好友的注册时间 */
//	private TextView viewRegisterTime = null;
//	/** 标签组件：好友的最近登陆时间 */
//	private TextView viewLatestLoginTime = null;
//	/** 图片组件：头像 */
//	private ImageView viewAvadar = null;
	
	private List<Map<String,Object>> saleList = null;
	
	private List<Map<String,Object>> basicList = null;
	
	/** 按钮：购买 */
	private Button btnPurchase = null;
	/** 按钮：加入购物车 */
	private Button btnAddToCar = null;
	
	private Button shopCar = null;
	
	private TextView shopCarCountView = null;
	
	private static int shopCarCount = 0;
	
	private TextView goodDetailTitleView = null;
	
	private View backBtn = null;
	
	// 本变量目前仅用于Activity被create时从Intent中取出来的商品信息对象.
	/**
	 * 为何不直接在 initDataFromIntent()方法中调用switchToFriends(..)呢？
	 * 原因在于，该方法里需要用到ui组件，而在initDataFromIntent()方法中Activity
	 * 的ui组件还没有初始化完毕，所以只能先暂存，然后再在后绪方法中使用即可 */
	private Device goodInfoForInit = null; 
	
	/** 商品颜色操作包装实现对象 */
	private GoodColorsWrapper goodColorsWrapper = null;
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void initDataFromIntent()
	{
		//解析从intent中传过来的数据
		goodInfoForInit = (Device)IntentFactory.parseGoodDetailActivityIntent(getIntent());
		saleList = convertString2List(goodInfoForInit.getDevice_sale_info());
		basicList = convertString2List(goodInfoForInit.getDevice_basic_info());
	}
	
	/** 
	 * 初始化界面组件.
	 * {@inheritDoc}
	 */
	@Override
	protected void initViews(Bundle savedInstanceState)
	{
		// 养成良好习惯：首先设置主layout，确保后绪的操作中使用到的组件都可以被find到
		setContentView(R.layout.common_mall_shop_layout_good_detail);
		//对自定义标题栏中的组件进行设定
//		this.getCustomeTitleBar().getRightGeneralButton().setVisibility(View.VISIBLE);
//		this.getCustomeTitleBar().getRightGeneralButton().setText("");
//		this.getCustomeTitleBar().getRightGeneralButton().setBackgroundResource(R.drawable.common_mall_shop_shopping_btn);
		
		// 初始化各种组件
		viewGoodName = (TextView)findViewById(R.id.common_mall_shop_layout_good_detail_goodNameView);
//		viewGoodDesc = (TextView)findViewById(R.id.common_mall_shop_layout_good_detail_goodDescView);
		viewGoodPrice = (TextView)findViewById(R.id.common_mall_shop_layout_good_detail_goodPriceView);
		viewCurrencyType = (TextView)findViewById(R.id.common_mall_shop_layout_good_detail_goodCurrencyTypeView);
		viewRefPrice = (TextView)findViewById(R.id.common_mall_shop_layout_good_detail_refPriceView);
//		viewForSex = (TextView)findViewById(R.id.common_mall_shop_layout_good_detail_goodForSexView);
//		viewLatestLoginTime = (TextView)findViewById(R.id.sns_friend_info_form_latestLoginTimeView);
		btnPurchase = (Button)findViewById(R.id.common_mall_shop_layout_good_detail_purchaseBtn);
		btnAddToCar = (Button)findViewById(R.id.common_mall_shop_layout_good_detail_addToShopcarBtn);
//		viewAvadar = (ImageView)findViewById(R.id.sns_friend_info_form_friendAdavarImageView);
		
		shopCar = (Button)findViewById(R.id.common_mall_shop_layout_good_detail_shopcar);
		shopCarCountView = (TextView)findViewById(R.id.common_mall_shop_layout_good_detail_shopcar_count);
		goodDetailTitleView = (TextView)findViewById(R.id.common_mall_shop_layout_good_detail_title);
		backBtn = findViewById(R.id.common_mall_shop_layout_good_detail_back);
		
		
		saleListView = (ListView)findViewById(R.id.common_mall_shop_good_detail_sale_info_listView);
		basicListView = (ListView)findViewById(R.id.common_mall_shop_good_detail_basic_info_listView);
		basicListView.setEnabled(false);
		saleListView.setEnabled(false);
		saleListView.setAdapter(new SimpleAdapter(this, saleList, R.layout.common_mall_shop_good_detail_sale_info_list_item, new String[]{"SHOW_TEXT"}, new int[]{R.id.common_mall_shop_good_detail_sale_info_item_text}));
		basicListView.setAdapter(new SimpleAdapter(this, basicList, R.layout.common_mall_shop_good_detail_basic_info_list_item, new String[]{"SHOW_TEXT"}, new int[]{R.id.common_mall_shop_good_detail_basic_info_item_text}));
		Utility.setListViewHeightBasedOnChildren(basicListView);
		Utility.setListViewHeightBasedOnChildren(saleListView);
		
		
		// 设置标题
		String detailTitle = $$(R.string.common_mall_shop_good_detail_title1);
		String goodDetailTitle = $$(R.string.common_mall_shop_good_detail_title2);
		
		goodDetailTitleView.setText(goodInfoForInit != null ? MessageFormat.format(detailTitle, goodInfoForInit.getDevice_short_name()) : goodDetailTitle);
		//
		this.setLoadDataOnCreate(false);
		
		// 根据Intent中传过来的U友信息数据，刷新UI界面显示
		this.refreshToView(goodInfoForInit);
		
		//
		goodColorsWrapper = new GoodColorsWrapper();
	}
	
	/**
	 * 将当前商品（区分颜色了）加入到购物车.
	 * 
	 * @param deltaQuantity 当前要增加到购物车中的数量
	 * @return 该商品、该颜色在购物车中的总数量
	 */
	private int addToCar(int deltaQuantity)
	{
		// 加入一个商品到购物车中
		return MallGlobal.getMallProviderInstance(this).getRobotimeMall().getShopCarProvider().addToCar(this
				, goodInfoForInit.getDevice_id()
				, goodColorsWrapper.getCurrentCheckedGoodColor().getColor_id()
				, goodColorsWrapper.getCurrentCheckedGoodColor().getColor_desc()
				, deltaQuantity);
	}
	
	@Override
	protected void initListeners()
	{
		btnPurchase.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View v)
			{
				// 当用户没用登陆时作未登陆的处理
				if(!MallGlobal.getMallProviderInstance(GoodDetailActivity.this).getRobotimeMall().isUserLogin())
					MallGlobal.getMallProviderInstance(GoodDetailActivity.this).getRobotimeMall().processForUserUnLogin(GoodDetailActivity.this);
				else
				{
					if(check())
					{
						// 购买时先加入一个商品到购物车中
						int sum = addToCar(1);
						startActivity(IntentFactory.createOrderComfirmActivityIntent(GoodDetailActivity.this));
					}
				}
			}
		});
		btnAddToCar.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View v)
			{
				if(check())
				{
					// 加入一个商品到购物车中
					int sum = addToCar(1);
					
					if(shopCarCountView.getVisibility() != View.VISIBLE)
						shopCarCountView.setVisibility(View.VISIBLE);
					shopCarCountView.setText(++shopCarCount + "");
							
					WidgetUtils.showToast(GoodDetailActivity.this
							,MessageFormat.format($$(R.string.common_mall_shop_good_detail_add_shop_car_toast), 
									goodInfoForInit.getDevice_short_name(), sum)
							, ToastType.OK);
				}
			}
		});
		
		shopCar.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View v)
			{
				startActivity(IntentFactory.createShopCarActivityIntent(GoodDetailActivity.this));
			}
		});
		
		backBtn.setOnClickListener(new OnClickListener()
		{
			
			@Override
			public void onClick(View v)
			{
				finish();
			}
		});
	}
	
	private boolean check()
	{
		if(goodColorsWrapper.getCurrentCheckedGoodColor() == null)
		{
			WidgetUtils.showToast(GoodDetailActivity.this, $$(R.string.common_mall_shop_good_detail_select_color_toast), ToastType.INFO);
			return false;
		}
		return true;
	}
	
//	// 去掉EVA通用类中的默认“返回”菜单项
//	public boolean onCreateOptionsMenu(Menu menu)
//	{
//		return false;
//	}
	
	//--------------------------------------------------------------------------------------------
	/**
	 * 从服务端查询数据并返回.
	 * 
	 * @param params loadData中传进来的参数，本类中该参数没有被用到
	 */
	@Override protected DataFromServer queryData(String... params)
	{
		return null;
	}
	//将已构造完成的完整的明细数据放入列表中显示出来
	@Override protected void refreshToView(Object dateToView)
	{
		if(dateToView != null && dateToView instanceof Device)
		{
			Device friendInfo = (Device)dateToView;

			viewGoodName.setText(friendInfo.getDevice_short_name());
//			viewGoodDesc.setText(friendInfo.getDevice_desc());
			viewGoodPrice.setText(friendInfo.getSale_price());
			viewCurrencyType.setText(""+ObjectFactory.createCurrencyTypeRenderer().getNameById(friendInfo.getSale_currency_type()));
			viewRefPrice.setText(String.valueOf(viewCurrencyType.getText() + friendInfo.getReference_price()));
			//加中划线并加清晰
			viewRefPrice.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
//			viewForSex.setText(friendInfo.getFor_sex().equals("1") ? $$(R.string.common_general_male) : $$(R.string.common_general_female));
		}
		else
		{
			Log.w(TAG, "dateToView="+dateToView);
			WidgetUtils.showToast(this, "dateToView="+dateToView, ToastType.WARN);
		}
	}
	
	protected void onResume()
	{
		shopCarCount = MallGlobal.getMallProviderInstance(this).getRobotimeMall().getShopCarProvider().getGoodsCount();
		if(shopCarCount == 0)
			shopCarCountView.setVisibility(View.GONE);
		else
		{
			shopCarCountView.setVisibility(View.VISIBLE);
			shopCarCountView.setText(shopCarCount + "");
		}
		super.onResume();
	}
	
	//------------------------------------------------------------------------------------------- inner class
	/**
	 * 商品颜色包装实现类.
	 * 
	 * <p>
	 * 一个商品有多种颜色，一个颜色对应多张照片.
	 * <p>
	 * 数据初始化好后，颜色切换按钮是固定的UI上的，但该颜色所对应的“图片画廊”、“图片指示器”是可据颜色随时动态切换的.
	 * 
	 * @author Jack Jiang, 2013-09-21
	 * @version 1.0
	 */
	private class GoodColorsWrapper
	{
		//** 各UI元素
		/** 商品所对应颜色的切换按钮父布局（一个商品有多种颜色，一个颜色对应多张照片） */
//		private ViewGroup layoutOfColorBtns1 = null;
		
		private GridView gridViewColorBtns = null;
		private MyGridViewAdapter myGridViewAdapter = null;
		
		/** 画廊（用于显示对应颜色的各图片）  */
		private Gallery galeryPics = null;
		
		private IndicationDotList mDotList = null;
		
//		private AnimationSet mAnimationSet;
		/** 商品图片指示器（与画廊中当前所显示的图片索引一一对应，用于指示画廊中的图片） */
//		private ViewGroup layoutOfIndicators = null;
		
		//** 各UI所对应的数据模型
		/** 画廊Adapter（数据模型与当前选中的颜色所相关的图片数据模型对应） */
		private PicsOfColorGalleryAdapter galleryAdapter = null;
		/** 画廊的图片指示器集合（数据模型与当前选中的颜色所相关的图片数据模型对应） */
//		private ArrayList<IndicatorImageView> galleryPicsIndicators = new ArrayList<IndicatorImageView>();
		/** 画廊中当前选是的图片索引值（本字段将在画廊的图片选中事件被触发时更新） */
		private int currentSelectedPicIndex = 0;
		
		/** 当前选中的商品颜色 */
		private Color currentCheckedGoodColor = null;
		private int currentCheckedGoodColorPosition = 0;
		
		public GoodColorsWrapper()
		{
			initViews();
			initListeners();
			
			// 刷新颜色、图片显示
			refreshDatasAsync();
		}
		
		/**
		 * 核心初始化方法.
		 */
		private void initViews()
		{
			galeryPics = (Gallery)findViewById(R.id.common_mall_shop_layout_good_detail_goodPicsGalery);
			mDotList = (IndicationDotList) findViewById(R.id.common_mall_shop_layout_good_detail_index_indication);
//			layoutOfIndicators = (ViewGroup)findViewById(R.id.common_mall_shop_layout_good_detail_goodPicIndicatorsLL);
//			layoutOfColorBtns1 = (ViewGroup)findViewById(R.id.common_mall_shop_layout_good_detail_goodColorsLL1);
			gridViewColorBtns = (GridView)findViewById(R.id.common_mall_shop_layout_good_detail_goodColorsGV);
			myGridViewAdapter = new MyGridViewAdapter(GoodDetailActivity.this, colorList, R.layout.common_mall_shop_layout_good_detail_girdview_item);
			gridViewColorBtns.setAdapter(myGridViewAdapter);
			gridViewColorBtns.requestFocus();
			
		
			
			// 设置gallery的adapter
			galleryAdapter = new PicsOfColorGalleryAdapter(GoodDetailActivity.this);
			galeryPics.setAdapter(galleryAdapter);

		}
		
		/**
		 * 初始化各组件的事件监听者.
		 */
		private void initListeners()
		{
			gridViewColorBtns.setOnItemClickListener(new OnItemClickListener()
			{
				@Override
				public void onItemClick(AdapterView<?> parent, View currentView, int position, long id)
				{
					//如果click按钮与当前选中按钮不一致
					if(currentCheckedGoodColorPosition != position)
					{
						//将选中按钮改为非选中状态
						parent.getChildAt(currentCheckedGoodColorPosition).setBackgroundDrawable(getResources().getDrawable(R.drawable.common_good_detail_color_nor));
						//当前按钮改为选中状态
						currentView.setBackgroundDrawable(getResources().getDrawable(R.drawable.common_good_detail_color_selected));
						currentCheckedGoodColorPosition = position;
						TextView tvColor =  (TextView) currentView.findViewById(R.id.common_mall_shop_layout_good_detail_girdview_item_radio);
						Color c = (Color)tvColor.getTag();
						switchColorPicsToShow(c.getPicsOfColor());
						currentCheckedGoodColor = c;
					}
					
				}
			});
			
			galeryPics.setOnItemClickListener(new OnItemClickListener()
			{
				@Override
				public void onItemClick(AdapterView<?> partent, View v, int position, long id)
				{
					Intent intent = new Intent(GoodDetailActivity.this ,GoodDetailPicShowerActivity.class);
					intent.putExtra("PicOfColor", currentCheckedGoodColor.getPicsOfColor());
					intent.putExtra("position", position);
					GoodDetailActivity.this.startActivity(intent);
				}
			});
			// 滑动gallery的图片时更新对应指示器的选中样式
			galeryPics.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() 
			{  
			    @Override  
			    public void onItemSelected(AdapterView<?> parent, View v,int position, long id) 
			    {
//			    	// 更新指示器显示状态
//			    	galleryPicsIndicators.get(currentSelectedPicIndex).setIndicatorSelected(false); // 先更新老的
//			    	galleryPicsIndicators.get(position).setIndicatorSelected(true);                 // 理更新新的
			    	mDotList.setIndex(position);
					// 保存当前被选中的索引
			    	currentSelectedPicIndex = position;
			    }  
			    
			    @Override  
			    public void onNothingSelected(AdapterView<?> arg0) 
			    {  
			    	//这里不做响应  
			    }  
			}); 
		}
		
		/**
		 * 异常从服务端加载商品对应的颜色数据并刷新到UI.
		 * 
		 * @see #refreshDatas(ArrayList)
		 */
		public void refreshDatasAsync()
		{
			new DataRefreshAsyncTask(GoodDetailActivity.this){
				/**
				 * 该商品的颜色数据（从服务端）加载成功后的处理方法.
				 * 
				 * @param colorsDataOfGood 商品的颜色数据集合
				 */
				@Override
				protected void processDataAfterSucess(ArrayList<Color> colorsDataOfGood)
				{
					refreshDatas(colorsDataOfGood);
				}
			}.execute(goodInfoForInit.getDevice_id());
		}
		
		/**
		 * 用指定的颜色数据刷新UI.
		 * 
		 * @param colorsDataOfGood
		 */
		private void refreshDatas(ArrayList<Color> colorsDataOfGood)
		{
			// ** 重置对应颜色选择按钮
//			layoutOfColorBtns1.removeAllViews();
//			colorList.clear();
			colorList.addAll(colorsDataOfGood);
			myGridViewAdapter.notifyDataSetChanged();
			
			if(colorsDataOfGood.size() > 0)
			{
				switchColorPicsToShow(colorsDataOfGood.get(currentCheckedGoodColorPosition).getPicsOfColor());
				currentCheckedGoodColor = colorsDataOfGood.get(currentCheckedGoodColorPosition);
			}
			
			// ** 按颜色逐个加入颜色切换按钮
//			for(int i = 0; i < colorsDataOfGood.size(); i++)
//			{
//
//				Color c = colorsDataOfGood.get(i);
//				// 一种颜色一个按钮
//				ColorSelectButton rb = new ColorSelectButton(GoodDetailActivity.this, c.getPicsOfColor()){
//					/**
//					 * 切换到对应颜色要做的事.
//					 * 
//					 * @param picsOfColor 该颜色所对应的图片
//					 */
//					@Override
//					protected void fireCheckted(ColorSelectButton v, ArrayList<Pic> picsOfColor)
//					{
//						// 切换该颜色对应的商品图片
//						switchColorPicsToShow(picsOfColor);
//						// 保存当前切换到的商品颜色
//						currentCheckedGoodColor = (Color)v.getTag();
//					}
//				}; 
//				
//				rb.setText(c.getColor_desc());
//				// 把它对应颜色对象暂存起来备用
//				rb.setTag(c);
////				if(layoutOfColorBtns1.getChildCount() < 5)
////				// 将颜色按钮加入布局文件
////					layoutOfColorBtns1.1ddView(rb);
//				gridViewColorBtns.addView(rb);
//				
//				// 默认显示的是第0种颜色
//				if(i == 0)
//					rb.setChecked(true);
//			}
			
			
		}
		
		/**
		 * 根据数据型重置指示器组件.
		 * 
		 * @param pics
		 */
		private void __resetIndicators(ArrayList<Pic> pics)
		{
			mDotList.setCount(pics.size());
			// 重置
//			galleryPicsIndicators.clear();
//			layoutOfIndicators.removeAllViews();
			
			// 加入新的
//			for(Pic p : pics)
			{
//				IndicatorImageView ii = new IndicatorImageView(GoodDetailActivity.this);
//				galleryPicsIndicators.add(ii);
//				layoutOfIndicators.addView(ii);
			}
		}
		
		/**
		 * 切换指定颜色的图片显示.
		 * 
		 * @param picsOfColor 该颜色所对应的图片明细数据
		 */
		private void switchColorPicsToShow(ArrayList<Pic> picsOfColor)
		{
			if(picsOfColor == null)
				return;
			
			// ** 重置当前选中图片索引的值
			currentSelectedPicIndex = 0;
			
			// 重置gallery
			galleryAdapter.setListData(picsOfColor);
			galleryAdapter.notifyDataSetChanged();
			
			// 重置指示器组件
			__resetIndicators(picsOfColor);
			
			// 设置中间显示的图（选中中间图片）（否则会默认选中第0个，
			// 那么左边就会有空白，看起来会很难看，仅此而已）
			if(picsOfColor.size() > 0)
			{
				int defaultSelected = picsOfColor.size()/2;
				// 画廊中的默认选中
				galeryPics.setSelection(defaultSelected);
//				galeryPics.performItemClick(galeryPics, picsOfColor.size()/2, -1);
				// 指示器的默认选中
//				galleryPicsIndicators.get(defaultSelected).setIndicatorSelected(true);
			}
		}

		public Color getCurrentCheckedGoodColor()
		{
			return currentCheckedGoodColor;
		}
	}
	
	//------------------------------------------------------------------------------------------------------------- utility class
	/**
	 * 商品颜色切换按钮实现类.
	 * 
	 * @author Jack Jiang, 2013-09-21
	 */
	private static abstract class ColorSelectButton extends RadioButton
	{
		private ArrayList<Pic> picsOfColor = null;
		
		public ColorSelectButton (Context context, ArrayList<Pic> picsOfColor)
		{
			this(context, null, picsOfColor);
		}
		public ColorSelectButton (Context context, AttributeSet attrs, ArrayList<Pic> picsOfColor)
		{
			super(context, attrs);	
			//
			this.picsOfColor = picsOfColor;
			//
			init();
		}

		private void init()
		{
//			this.setBackgroundDrawable(getResources().getDrawable(R.drawable.common_good_detail_color_selector));
//			this.setText(c.getColor_desc());
//			this.setTextSize(Utility.px2dip(GoodDetailActivity.this, 30));
			LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);//Utility.px2dip(GoodDetailActivity.this, 180));
			this.setLayoutParams(lp);
			this.setButtonDrawable(R.drawable.null_pic);
			this.setTextColor(((Activity)this.getContext())
					.getResources().getColor(R.color.rb_common_m00_text_black_666666_color));
			LayoutParams mlp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
//			//this.setMargins(5, 5, 5, 5); // setMargins don't work
//			this.setPadding(this.getPaddingLeft()-5, 0, 15, 0);   // but setPadding is ok
			this.setPadding(this.getPaddingLeft()+2, 6, 10, 6);   // but setPadding is ok
			this.setLayoutParams(mlp);
//			// default status
//			this.setIndicatorSelected(false);
			
			this.setOnCheckedChangeListener(new OnCheckedChangeListener(){
				@Override
				public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
				{
					if(isChecked)
						fireCheckted(ColorSelectButton.this, picsOfColor);
				}
			});
		}
		
		/**
		 * 切换到对应颜色要做的事.
		 * 
		 * @param picsOfColor 该颜色所对应的图片
		 */
		protected abstract void fireCheckted(ColorSelectButton v, ArrayList<Pic> picsOfColor);
	}
	
	/**
	 * 商品颜色、图片数据异步（从服务端）加载实现类.
	 * 
	 * @author Jack Jiang, 2013-09-21
	 */
	private static abstract class DataRefreshAsyncTask extends AsyncTask<Object, Integer, DataFromServer>
	{
		private Activity activity = null;
		
		public DataRefreshAsyncTask(Activity activity)
		{
			this.activity = activity;
		}
		
		/**
		 * 处理耗时数据前先显示进度条.
		 */
		@Override
		protected void onPreExecute()
		{
//			_showProgessBar();
		}
		
		/**
		 * 在后台执行查询数据.
		 * 
		 * @param parems 参数没有意义
		 * @return 查询结果，将传递给onPostExecute(..)方法
		 */
		@Override
		protected DataFromServer doInBackground(Object... parems) 
		{
			DataFromServer dfs = MallGlobal.getMallProviderInstance(activity).getRobotimeMall().getNoNeedAuthedService().sendObjToServer(
					DataFromClient.n()
					.setProcessorId(CommonProcessorConst.PROCESSOR_SHOP_NO$NEED$AUTHED)
					.setJobDispatchId(com.x52im.mall.shop.dto.JobDispatchConst.SHOP_GOODS_MGR_NO$NEED$AUTHED)
					.setActionId(SysActionConst.ACTION_APPEND1)
					.setNewData(parems[0])
			);
			
			return dfs;
		}
		
		/**
		 * <p>
		 * 用于处理queryData返回结果，并取消进度条的显示.<br>
		 * 最终的数据结果处理将交由方法 {@link #onPostExecuteImpl(Object)}处理.
		 * </p>
		 * 
		 * @param dfs doInBackground里传递过来的就是从服务端返回的处理结果对象
		 * @see #onPostExecuteImpl(Object)
		 */
		@Override
		protected void onPostExecute(DataFromServer dfs) 
		{
			// 服务端数据成功返回
			if (dfs != null	&& HttpServiceFactory4A.isSuccess(dfs, activity))
			{
				Log.d(TAG, "--成功");
//				//隐藏进度提示
//				_hideProgessBar();
				
				//对从服务端取过来的数据进行解析
				@SuppressWarnings("unchecked")
				ArrayList<Color> dtoFromServer = (ArrayList<Color>)dfs.getReturnValue();
				if(dtoFromServer != null)
				{
//					refreshColor(dtoFromServer);
					processDataAfterSucess(dtoFromServer);
				}
			} 
			else
			{
				Log.d(TAG, "--失败");
			}
		}
		
		/**
		 * 该商品的颜色数据（从服务端）加载成功后的处理方法.
		 * 
		 * @param colorsDataOfGood 商品的颜色数据集合
		 */
		protected abstract void processDataAfterSucess(ArrayList<Color> colorsDataOfGood);
//		protected abstract void _showProgessBar();
//		protected abstract void _hideProgessBar();
//		protected abstract void _dataLoadSucess();
	}
	
	/**
	 * 商品图片明细适配器实现类.
	 * 
	 * @author Jack Jiang, 2013-09-21
	 * @version 1.0
	 */
	private static class PicsOfColorGalleryAdapter extends AListAdapter2<Pic>
	{
		private AsyncBitmapLoader asyncLoader = null; 
		/** 记录选中的ListView的行索引值以备后用（目前是在：单击、长按2类事件中保存了此索引值）.*/
		private int selectedListViewIndex = -1;

		public PicsOfColorGalleryAdapter(Activity context)
		{
			// R.layout.chatting_list_view_bottom_waves_list_item
			super(context, R.layout.common_mall_shop_layout_good_detail_pic_item);
			this.asyncLoader = new AsyncBitmapLoader(MallGlobal.getMallProviderInstance(
					context).getRobotimeMall().getGoodPicsCachedDirPath());  
		}

		@Override
		public View getView(final int position, View convertView, ViewGroup parent)
		{
			try
			{
				//列表item上的：
	//			TextView viewText = null;
				//列表item上的：
				ImageView viewImage = null;
	
				//---------------------------------------------------------------------------------------- （1）UI初始化
				//当的item布局实例已经存在（不在存，意味着这个item刚好从不可见区移到可见区时）
				//** 根据android的列表ui实现，为了节比资源占用，假如列表有100行而可见区显示5行，那么任何时候
				//** 这个列表中只会有5个item的UI存在，其它的item都是当被转到可见区时自动把自
				//** 已的数据实时地更新列UI上，以便查看，也就是说item的UI并不是与后台数据一
				//** 一对应的，所以正如API文档里说的，convertView并不能确保它总能按你的想法保持不为null
				boolean needCreateItem = (convertView == null);
				//正在操作的列表行的数据集
				final Pic rowData = listData.get(position);
				if (needCreateItem)
					//明细item的UI实例化
					convertView = layoutInflater.inflate(itemResId, null);
				//item里的操作组件实例
	//			viewText = (TextView) convertView.findViewById(R.id.common_mall_shop_layout_good_detail_pic_item_textView);
				viewImage = (ImageView) convertView.findViewById(R.id.common_mall_shop_layout_good_detail_pic_item_imageView);
	
				//---------------------------------------------------------------------------------------- （2）增加事件处理器
				//各操作组件的事件监听器只需要在convertView被实例化时才需要重建（convertView需要被实例化
				//当然就意味着它上面的所有操作组件都已经重新新建了）
				//** 关于事件处理器的说明：事件处理器的增加其实可以不这么麻烦，直接每getView一次就给组件new一个处理器，
				//** 这样做的好处是简单，但显然存在资源浪费（每刷新一次view就新建监听器）。而现在的实现就跟Android的列表
				//** 实现原理一样，在切换到下一组item前，监听器永远只有一屏item的数量（刷新时只需要即时刷新对应item的数据到
				//** 它的监听器里），这样就节省了资源开销！
				if(needCreateItem)
				{
					//
				}
	
				//---------------------------------------------------------------------------------------- （3）
	//			viewText.setText(rowData.getPic_desc());
				//
				//根据图片URL去查找内存缓存有没有对应的Bitmap对象，并传递回调方法，如果没有，则等下载完毕回调  
				Bitmap bitmap = asyncLoader.loadBitmap(viewImage,   
						MallGlobal.getMallProviderInstance(this.getContext()).getRobotimeMall().GOODS_PIC_HTTP_ROOT_URL()+rowData.getPic_path(),  
						new ImageCallBack()  
						{  
							@Override  
							public void imageLoad(ImageView imageView, Bitmap bitmap)  
							{  
//								Log.w(GoodDetailActivity.class.getSimpleName(), "【MALL】See here!!!!!!!!!!!!!!!!!!!!!"+bitmap.getWidth());
								imageView.setImageBitmap(bitmap);  
								
								// ## 非常奇怪的一个问题：当网络下载的图片完成时会回调至此，但图片数据明
								// ## 明有了却不能刷新显示之，目前为了它能显示就低效地notifyDataSetChanged
								// ## 一下吧，以后看看什么方法可以单独刷新（否则每一次都得刷新所有可见区），
								// ## 有可能是android的listview机制性问题
								PicsOfColorGalleryAdapter.this.notifyDataSetChanged();
							}  
						}
				);  
	
				if(bitmap == null)  
				{  
					viewImage.setImageResource(R.drawable.common_mall_default_pic);
				}  
				else  
				{  
	//				Bitmap old = ((Bitmap)viewImage.getDrawingCache());
	//				if(old != null)
	//				{
	//					((Bitmap)viewImage.getDrawingCache()).recycle();
	//				}
					viewImage.setImageBitmap(bitmap);  
				}  
			}
			catch (OutOfMemoryError e) 
			{
		    	 Log.w(GoodDetailActivity.class.getSimpleName(), "商品图片显示内存不足,建议退出程序并重新进入.", e);
		    	 Toast.makeText(getContext(), "商品图片显示内存不足,建议退出程序并重新进入.",Toast.LENGTH_SHORT).show();
		    	 //TODO: out of memory deal..
		    }

			return convertView;
		}

		@SuppressWarnings("unused")
		public int getSelectedListViewIndex()
		{
			return selectedListViewIndex;
		}
		@SuppressWarnings("unused")
		public void setSelectedListViewIndex(int selectedListViewIndex)
		{
			this.selectedListViewIndex = selectedListViewIndex;
		}
	}
	
	/**
	 * 一个页面指示器组件默认实现类.
	 * 
	 * @author Jack Jiang, 2013-07-24
	 * @version 1.0
	 */
	private static class IndicatorImageView extends ImageView
	{
		public IndicatorImageView (Context context)
		{
			this(context, null);
		}

		public IndicatorImageView (Context context, AttributeSet attrs)
		{
			super(context, attrs);	

			init();
		}

		private void init()
		{
			LayoutParams mlp = new LayoutParams(
					LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
			//this.setMargins(5, 5, 5, 5); // setMargins don't work
			this.setPadding(5, 5, 5, 5);   // but setPadding is ok
			this.setLayoutParams(mlp);
			// default status
			this.setIndicatorSelected(false);
		}

		public void setIndicatorSelected(boolean selected)
		{
			if(selected)
				this.setImageResource(R.drawable.common_mall_guide_dot_black);
			else
				this.setImageResource(R.drawable.common_mall_guide_dot_white);
		}
	}
	
	private List<Map<String,Object>> convertString2List(String resource)
	{
		List<Map<String,Object>> resList = new ArrayList<Map<String,Object>>();
		
		if(!CommonUtils.isStringEmpty(resource))
		{
			String[] arr = resource.split("[||]");
			for(String s : arr)
			{
				if(CommonUtils.isStringEmpty(s))
					continue;
				Map<String,Object> resMap = new HashMap<String,Object>();
				resMap.put("SHOW_TEXT", "· " + s);
				resList.add(resMap);
			}
		}
		return resList;
	}
}
